package paylayer

import (
	"strconv"
	"strings"
	"dhfshop/utils/uuid"
	"dhfshop/models/misc"
	"encoding/json"
	"dhfshop/models/isv"
	"dhfshop/models/shopping"
	"github.com/astaxie/beego"
	"thirdpaysdk/api/superpay"
	"dhfshop/service/redisgo"
	"github.com/pkg/errors"
)

func OrderSuperPay(appId,openId string,acPay *isv.AcPayParams,order *shopping.ValueOrder)(rsp PayResponse,prepayId string, err error) {
	var cacheValue string
	
	mchId := acPay.MchId
	appSecret := acPay.Appkey
	currency := acPay.MediaId
	orderStr := strconv.FormatInt(order.OrderId,10)
	des := "订单" + "[" + orderStr + "]"
	callBackUrl := beego.AppConfig.String("WXPayNotify") + "/public/superpay/notify"
	storeName := appId
	receviceId := acPay.SubMchId
	payAmount := strconv.FormatFloat(float64(order.Payment), 'f', -1, 32)
	cacheKey := "payorder_" + orderStr
	redisconn := redisgo.GetInstance()
	if cacheValue, err = redisconn.GetString(cacheKey); err == nil && len(cacheValue) > 5  {
		newOrderId, _:= uuid.GetSnowFlakeId(uuid.Worker)
		beego.Debug("OrderSuperPay update order_id","old:",order.OrderId,"new:",newOrderId)
		if err = shopping.UpdateOrderId(order.OrderId, newOrderId); err == nil {
			if err = shopping.UpdateOrderItemId(order.OrderId, newOrderId); err == nil {
			   orderStr = strconv.FormatInt(newOrderId,10)
			}else{
			   beego.Debug("UpdateOrderItemId:", err.Error())
			   return
			}
		} else {
		   beego.Debug("UpdateOrderId:", err.Error())
		   return
		}
	}
	payInfo, err := superpay.Unifield(mchId,appSecret,callBackUrl,storeName,receviceId,orderStr,
	                                      openId,currency,payAmount,des,payAmount,"1",des,"3d")
	if err != nil {
		err = errors.Wrap(err, "Unifield... ")
		beego.Debug(err.Error())
		return 
	}
	prepayId = strings.Replace(payInfo.Package, "prepay_id=", "", -1)
	
	//更新订单支付方式编号
	order.PayWayCode = 11
	shopping.UpdateOrderPayWayCode(order)
	payRsp := misc.WxResponse{}
	payRsp.AppId = payInfo.AppId
	payRsp.NonceStr = payInfo.NonceStr
	payRsp.Package = payInfo.Package
	payRsp.SignType = payInfo.SignType
	payRsp.TimeStamp = payInfo.TimeStamp
	payRsp.PaySign = payInfo.PaySign
	if tempJson, e := json.Marshal(payRsp); e == nil { 
	   rsp.WxpayRsp = string(tempJson)
	}
	cacheKey = "payorder_" + orderStr
	var payInfoCache *PayInfoCache = new(PayInfoCache)
	payInfoCache.AppId = appId
	payInfoCache.MchId = acPay.MchId
	payInfoCache.AppKey = acPay.Appkey
	payInfoCache.OrderKind = "ESHOP_ORDER_PAY"
	payInfoCache.Currency = currency
	if payInfoJSON, e := json.Marshal(payInfoCache); e == nil { 
		if _, err = redisconn.Set(cacheKey, string(payInfoJSON), 3*24*60*60); err != nil {  
			beego.Debug("SETEX", err.Error())
		}
	}
	return
}

func ChargeSuperPay(appId,openId,outTradeNo string,acPay *isv.AcPayParams,amount float32)(rsp PayResponse,prepayId string,err error){
    mchId := acPay.MchId
	appSecret := acPay.Appkey
	currency := acPay.MediaId
	des := "账户充值" + "[" + outTradeNo + "]"
	callBackUrl := beego.AppConfig.String("WXPayNotify") + "/public/royalpay/notify"
	storeName := appId
	receviceId := acPay.SubMchId
	payAmount := strconv.FormatFloat(float64(amount), 'f', -1, 32)
	payInfo, err := superpay.Unifield(mchId,appSecret,callBackUrl,storeName,receviceId,outTradeNo,
	                                      openId,currency,payAmount,des,payAmount,"1",des,"3d")
	if err != nil {
		err = errors.Wrap(err, "MicroAppPay... ")
		beego.Debug(err.Error())
		return 
	}
	prepayId = strings.Replace(payInfo.Package, "prepay_id=", "", -1)
	payRsp := misc.WxResponse{}
	payRsp.AppId = payInfo.AppId
	payRsp.NonceStr = payInfo.NonceStr
	payRsp.Package = payInfo.Package
	payRsp.SignType = payInfo.SignType
	payRsp.TimeStamp = payInfo.TimeStamp
	payRsp.PaySign = payInfo.PaySign
	if tempJson, err := json.Marshal(payRsp); err == nil {
		rsp.WxpayRsp = string(tempJson)
	}
	redisconn := redisgo.GetInstance()
	cacheKey := "payorder_" + outTradeNo
	var payInfoCache *PayInfoCache = new(PayInfoCache)
	payInfoCache.AppId = appId
	payInfoCache.MchId = acPay.MchId
	payInfoCache.AppKey = acPay.Appkey
	payInfoCache.OrderKind = "MEMBER_CHARGE"
	payInfoCache.Currency = currency
	if payInfoJSON, err := json.Marshal(payInfoCache); err == nil { 
		if _, err = redisconn.Set(cacheKey, string(payInfoJSON), 3*24*60*60); err != nil {  
			beego.Debug("SETEX", err.Error())
		}
	}
	return
}

func CommonSuperPay(appId,openId,orderId,body,kind string,acPay *isv.AcPayParams,amount float32)(rsp PayResponse,prepayId string, err error){
    mchId := acPay.MchId
	appSecret := acPay.Appkey
	currency := acPay.MediaId
	callBackUrl := beego.AppConfig.String("WXPayNotify") + "/public/royalpay/notify"
	storeName := appId
	receviceId := acPay.SubMchId
	payAmount := strconv.FormatFloat(float64(amount), 'f', -1, 32)
	payInfo, err := superpay.Unifield(mchId,appSecret,callBackUrl,storeName,receviceId,orderId,
	                                      openId,currency,payAmount,body,payAmount,"1",body,"3d")
	if err != nil {
		err = errors.Wrap(err, "MicroAppPay... ")
		beego.Debug(err.Error())
		return 
	}
	prepayId = strings.Replace(payInfo.Package, "prepay_id=", "", -1)
	payRsp := misc.WxResponse{}
	payRsp.AppId = payInfo.AppId
	payRsp.NonceStr = payInfo.NonceStr
	payRsp.Package = payInfo.Package
	payRsp.SignType = payInfo.SignType
	payRsp.TimeStamp = payInfo.TimeStamp
	payRsp.PaySign = payInfo.PaySign
	if tempJson, err := json.Marshal(payRsp); err == nil { 
	   rsp.WxpayRsp = string(tempJson)
	}
	redisconn := redisgo.GetInstance()
	cacheKey := "payorder_" + orderId
	var payInfoCache *PayInfoCache = new(PayInfoCache)
	payInfoCache.AppId = appId
	payInfoCache.MchId = acPay.MchId
	payInfoCache.AppKey = acPay.Appkey
	payInfoCache.OrderKind = kind
	payInfoCache.Currency = currency
	if payInfoJSON, err := json.Marshal(payInfoCache); err == nil { 
		if _, err = redisconn.Set(cacheKey, string(payInfoJSON), 3*24*60*60); err != nil {  
			beego.Debug("SETEX", err.Error())
		}
	}
	return
}

